home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 1 Issue 2
/
PDCD-1 - Issue 02.iso
/
_editors
/
editors
/
_zap
/
!Zap
/
Docs
/
E-Command
< prev
next >
Wrap
Text File
|
1994-10-12
|
21KB
|
527 lines
*************************************************************************
* >E-Command Documents how to add commands to Zap *
*************************************************************************
As mentioned in the ReadMe file, commands are added to Zap by registering a
table of commands when the module providing the extra commands initialises.
You should use the call Zap_AddCommands to register the table. The table has
the format below. All offsets are from your module start unless otherwise
indicated.
#0 Offset of table from start of module (so Zap can convert the
offsets below into addresses).
#4 Offset from module start of 'Zap service call code' or 0
if none. Zap calls this entry point to tell you about
various things - see the section below.
#8 List of commands, terminated by a zero word. Each element
of the list has the format:
<command name>+<0 byte terminator>+
<ZERO bytes padding until word aligned>+
<word giving command offset from module start>
The command name must be in UPPER CASE in this table. In general, command
names are not case sensitive, but they are converted to upper case in order
to search for them in the command tables. The characters padding to the next
word alignment MUST be ZEROs as the table is searched through in words not
in bytes.
When a command is found in the table, its address is calculated, and
henceforth the command is referred to by its address. This unfortunately
means that I cannot pass the command your module workspace when the command
is called as I do not know which module the command lies in. This is not
usually a problem however as you may claim workspace from Zap's heap. If this
is not sufficient, then you will just have to store the address of your
workspace in the module itself and read it when you are called (until I work
out a better method).
The address of the command is of course the address called when the command
is executed. However, at offset -4, the word before the first instruction of
the command, some flags are stored. These flags determine what type of
parameter the command takes and how the command interacts with the
minibuffer and menus. This word must be filled in. It's meaning is summarised
below. Greater detail is given further down the file.
b0 Set if the command doesn't need R10 on entry (eg called from
b1 Set if the command doesn't need R8 on entry a menu).
b2 Set if the command doesn't need R9 on entry
b3-b5 Argument type for the command:
0 = Command takes no parameters
1 = Command takes a list of bytes as parameter
2 = Command takes a list of words as parameter
3 = Command takes a string as parameter
4 = Command takes a block of data as parameter
5-7 reserved
b6 Set if you wished to be called before minibuffer opened
b7 Set if you wish to be called after every minibuffer update
b8 Set if you wish to be called before a key is inserted into
the minibuffer (and possibly alter it).
b9 Set if you want TAB to complete file names in the minibuffer
b10 Set if you may want to kill the minibuffer when it starts up.
b11 Set if you may want minibuffer to remain open when command finished.
b12 Set if Universal arg should muliply R1 by the number of times to do.
b13 Set if command should be called repeatedly with R1 smaller.
b14 Set if the command should not be executed when loading a file.
b15 Set if the command is 'tickable' when on a menu entry.
b16 Set if the command can create a submenu or leaf window.
b17 Set if the command can provide a default string for a menu entry.
b18 Set if the command wishes to provide the menu entry text.
b19 Set if the command wishes to specify the submenu.
b20 Set if the command may wish to remove the menu entry.
b21-b31 Reserved - set to 0
The entry/exit conditions of your command depend on your flags word as I will
detail below. When the command is called the registers have the meaning:
R0 = input data for the command (dependent on R2 & command type - see below)
R1 = length of input data (dependent on R2 & command type - see below)
R2 = action code (details below)
R8 = window of the input caret (see E-Windows) (unless flags b1 set)
R9 = file block associated with R8 (see E-File) (unless flags b2 set)
R10 = cursor block pointer of input cursor (see E-Cursors)
(unless flags b3 set) (This is car_cursor if the cursors are combined
and car_input if they are split - see E-Vars).
R11 = undefined
R12 = Zap's workspace
R13 = small FD stack
ALL calls to your command have these registers set up. The descriptions of R0
and R1 given above are for action code R2=0 (execute the command). In general
their meaning will be dependent on R2 and are undefined otherwise. Note that
you are only called with the action codes you request via your flags word so
do not need to test for all possible action codes.
On exit from a command you may corrupt the registers R0-R11 and the flags.
You should return V flag set and R0=error block on error. Some of the calls
with R2<>0 require you to return a result in R0. To detail the actual meaning
of R0-R2 I have partitioned into cases below. Registers not mentioned are
undefined.
If you want to call a command yourself, then please use the call
Zap_ProcessCommand or Zap_CommandString. All calls from Zap are made by this
method. See the file 'Commands' for the syntax used when typing a command
into the keys file, or sending it to Zap_CommandString.
NB Only command calls with R2=0 or R2=1 are learnt. All other calls are
regarded as 'setup' calls and are not learnt.
************************
* Details of flag bits *
************************
Bit 0
-----
If this bit is set then R10 is undefined on entry. If it is clear then the
current position of the input cursor will be read if R10 is not specified (ie
is 0) when Zap_ProcessCommand is called. Note that reading the current
input cursor position may change R8 and R9 as well.
This is useful when the command is called from a menu. The menu may not be on
the window with the input focus. If this bit is set then the command can act
on the menu the window is on, where as if it is clear then it will always act
on the window with the input focus. Thus it should be set for any command
which only affects the window state and doesn't need to know the cursor
position.
Bit 1
-----
If this bit is set then R8 either points to a window or is 0 on entry. If 0
then the command is being called from the options menu to change the default
state. If the bit is clear and Zap_ProcessCommand is called with R8=0 then an
error is given.
Thus this bit should be set for commands which don't need to know where the
cursor is and can change the default options as well as the current window
state. If this bit is set then you should also set Bit 0.
Bit 2
-----
As for Bit 1 except that the file pointer R9 is checked instead of R8. If the
command is called from the options menu then both R8 and R9 will be 0.
Bits 3-5
--------
These determine what type of data the command takes. When the command is
executed it is called with R2=0. In general the meaning of R2>0 is documented
under the Bit with value R2. Note that Bits 12 and 13 are used in deciding
which value is passed in R1. When the command is called with R2=0 additional
information is passed in R3:
R3 = b0 Set => This command was executed as the last command as well.
(eg to spot cumulative ctrl K's/Yanks).
b1-b27 => Reserved
b28-b31=> Top bits of R2 when command called via Zap_ProcessCommand.
Data type None (0) is called with:
R0=undefined
R1=number of times the key has been pressed (depends on flags bits):
Suppose the key has been buffered a total of m times. Suppose also that
Universal argument (^U) is active and that the user has requested a
repetion of n times. (n=1 if universal argument not active).
Ie, Zap_ProcessCommand has been called with R1=m. Then:
b12=0 & b13=0 => Command is called n times with R1=m
b12=1 & b13=0 => Command is called once with R1=m*n
b12=0 & b13=1 => Command is called m*n times with R1=1
b12=1 & b13=1 => Command is called m times with R1=n
ie b12=1 => R1 is multiplied by n (the universal argument)
b13=1 => Called an extra m times with R1 divided by m.
R2=0 to execute the command.
Data type Byte list (1):
If the command takes a byte parameter, then when the keyboard input is
buffered, the bytes are buffered in a list as well. Hence the sequence
of keypresses: CHAR 65,CHAR 66,CHAR 67 will cause the command CHAR to be
called once with data list 65,66,67 (if b13=0).
R0=pointer to a list of the bytes
R1=number of bytes in the list (depends on flag bits):
If m,n are as above (ie Zap_ProcessCommand has been called with R1=m,
R0 pointing to a list of m bytes, and universal command repeat=n) then:
b12=0 & b13=0 => Command is called n times with R1=m and the list of
bytes pointed to by R0 is m long.
b12=1 & b13=0 => Command is called once with R1=m*n and the list
of bytes pointed to by R0 is m*n long. Ie, the
list passed to Zap_ProcessCommand has been
duplicated n times.
b12=0 & b13=1 => Command is called m*n times with R1=1 and
R0 pointing to the single byte argument. (R0
incremented between command calls and wraps round).
b12=1 & b13=1 => Command is called m times with R1=n and R0 pointing
to the single byte argument. (R0 is incremented by
1 byte on each command call so it covers the list
of m bytes passed to Zap_ProcessCommand).
R2=0 to execute the command.
Data type Word list (2):
The details are the same as for Byte list typed data except that R0 points
to a list of words and R1 is the number of words (not bytes) in the list.
Data type String (3) is called with:
R0=pointer to the string (zero terminated)
R1=number of times key pressed (as for data type None above)
R2=0 if the string was specified (eg INSERT "Wibble")
1 if the string wasn't specified (eg INSERT) but has been typed into
the minibuffer (R0 points to the minibuffer contents in this case)
and then RETURN has been pressed.
You can control the minibuffer, and the way the string is entered by using
bits 6-11 as documented below. Please set bit 6 and add a prompt where
possible. Your command should end up taking the same action regardless of
whether R2=0,1 for when learnt sequences are played back you are always
called with R2=0.
Data type Block (4) is called with:
R0=pointer to a data block (of command dependant format)
R1=number of times key pressed (as for data type None above)
R2=0 to execute the command.
This is used by the command MULTICOMMAND which is used internally within
Zap to execute a compiled list of other commands. You cannot use this type
of command in the Keys file as there is no way to specify a parameter.
Bit 6
-----
This bit is only used if the command takes a string parameter and it has not
been supplied. The minibuffer is opened in this case and, if this bit is set,
you are called to supply a prompt and add a default string after the prompt
if you like. You are called with R2=6 (R0,R1 undefined). See also bit 10.
The minibuffer is cleared before you are called and opened on screen AFTER
you return. Use Zap_MiniPrompt to add the promt and Zap_MiniWrite to alter
the contents of the rest of the minibuffer.
Bit 7
-----
This bit is only used if the command takes a string parameter and the
minibuffer has been opened. If this bit is set then you are called AFTER each
key has been inserted into the minibuffer so you can examine its contents.
You are called with:
R0=pointer to minibuffer contents (after the prompt)
R1=undefined
R2=7
The minibuffer is updated on screen after you return.
Bit 8
-----
This bit is only used if the command takes a string parameter and the
minibuffer has been opened. If this bit is set then you are called BEFORE
each key has been inserted into the minibuffer. You are called with:
R0=pointer to minibuffer contents (after the prompt)
R1=undefined
R2=&8000+Zaps internal key number of the key about to be inserted into
the minibuffer.
and you should return:
R0=-1 => leave the minibuffer unaltered - key not inserted (but you will
be called again if b7 is set).
0-&1FF => insert that key (Zap internal key number). Hence you will
usually exit via SUB R0,R2,#&8000. Returning &1B (Escape) will cause
the minibuffer to be closed.
&8000+key number => The minibuffer is quitted as if return had been
pressed (ie you are called with R2=1 etc) and the the indicated key
is acted on as if typed in the editing window.
You should use this call to trap insertions of TAB and make it act as a
completion key. Filename completion can be done automatically - see b9.
Bit 9
-----
If set then the TAB key automatically acts a 'filename completion' in the
minibuffer.
Bit 10
------
This bit is only used if the command takes a string parameter and the
minibuffer has been opened and bit 6 is also set. When you are called with
R2=6 then if bit 10 is also set you should return with:
R0=0 => continue as usual - ie open the minibuffer.
1 => total abort - you are opening your own window or something.
>1 => abort the minibuffer and execute the command as normal with R2=0
and with parameter the string pointed to by this R0.
NB Do not execute the command on this call - it will not be leant. This is
why you should pass the argument back in R0.
Bit 11
------
This bit is only used if the command takes a string parameter and the
minibuffer has been opened. When the user presses return the minibuffer is
usually closed after you have been called with R2=1 to execute the command.
If this bit is set then you can return a value in R0 (from being called with
R2=1) to stop this:
R0=0 => close the minibuffer as usual.
1 => leave the minibuffer open.
Bit 12-13
---------
These control the value of R1 when your command is called with R2=0. See Bits
3-5 for more details.
Bit 14
------
If set then the command is regarded as 'unsafe'. Ie, it could possibly be
used in a Trojan an should not be executed automatically on the loading of a
text file by specifying it in the first few lines of the file. The OSCLI
command is a good example of this.
Bit 15
------
This bit is only used if the command is used on a menu entry. If set then
you are asked whether the menu item should be ticked or shaded. You are
called when the menu entry is opened with:
R0=command data (pointer to byte/word/string)
R1=1
R2=15
R10 need not be valid even if b1 is clear (R10=0 if not valid)
and you should return
R0 = b0 set => menu item should be ticked
b1 set => menu item should be shaded
b2+ reserved - set to 0
Bit 16
------
This bit is only used if the command is used on a menu entry. If set then it
indicates that the command can be used as a submenu pointer. The submenu
warning bit is set and when the user tries to open the submenu you are called
with R2=16 and should return:
R0 = window handle of a leaf window to open off the menu
OR pointer to a wimp menu structure to open with Zap data at
negative offsets (see E-Menu).
For example the command 'Save' opens the 'Save diaglogue box' and returns the
window handle of it. This is compatable with the normal action of the Same
command when executed which is to open the box.
If bit 16 is clear and your command is used as a submenu then instead a
writable icon is produced and the contents sent to the command when the user
clicks on it. See bit 17.
Bit 17
------
This bit is only used when the command is used as a submenu pointer in the
'menus' file and bit 16 is clear. In this case a writable menu icon is
provided for the user to type in the command argument. It this bit is set
then you are asked to provided (1) a title for the menu containing the
writable icon (2) a default string to place in the icon when the menu is
created (ususally a default value) (3) the size of the buffer in the writable
icon. You are called with R2=17 and
R0=0 => Return R0 as a pointer to the title string to use for the menu
(a maximum of 12 characters long and zero terminated).
R0=1 => If your command is of type 3 (string) then:
Return R0 as a pointer to the string to insert in the buffer
OR 0 to clear the buffer
OR -1 to leave the buffer as it currently is.
OR bit 31 set and +ve integer to insert in b0-b30
If your command is of type 1/2 (byte/word) then:
Return R0 as a pointer to the number to insert in the buffer
OR 0 to clear the buffer
OR -1 to leave the buffer unaltered.
Set b31 of R0 if you want the number inserted in hex.
R0=2 => Return R0 as the size in characters the buffer should be.
R0>2 => Ignore - I may add further reason codes in future.
If bit 17 is clear then this call is handled for you and the default values
used are:
(1) The title string is set to the name of the command as appearing in the
menus file.
(2) Buffer is left unchanged when the menu is updated.
(3) Buffer is made 16 characters wide if command takes a string argument
or 8 if it takes a numerical argument.
Bit 18
------
This is only used when the command is used on a menu. If set and the menu
file contains a string of spaces as the menu entry text then you are called
to provide replacement text for the menu entry. The number of spaces in
the menu entry text defines the size of the buffer reserved for the
string. This is only called when the menu is initially created at the moment.
You are called with:
R0=pointer to command data (byte/word/string)
R1=1
R2=18
and should return
R0=pointer to text for the menu item (which may be clipped by Zap if it
doesn't fit in the buffer).
Bit 19
------
This is only used when the command is used on a menu. If set and the menu
file contains no submenu pointer for this menu entry then you are called to
provide replacement submenu pointer for this menu entry. This is only
called when the menu is initally created at the moment. You are called with:
R0=pointer to command data (byte/word/string)
R1=1
R2=19
and should return
R0=pointer to submenu (in Zap-Wimp format) or 0 for none.
Bit 20
------
This is only used when the command is used on a menu. If set then you are
asked whether the menu item should be omitted from the menu (for example the
mode it accesses doesn't exist). This is only called when the menu is
initally created at the moment. You are called with:
R0=pointer to command data (byte/word/string)
R1=1
R2=19
and should return
R0=b0 set to remove the menu item
b1-31 reserved (set to 0)
Bit 21-31
---------
Reserved - must be 0.
************
* EXAMPLE *
************
The code below implements a simple command which asks you to enter a number
into the minibuffer and then switches to that display mode. FNcall is a macro
which calls the named Zap entry point (see E-Zapcalls for its definition).
EQUD (3<<3)+(1<<6) \ string argument + ask for prompt
.command_start
STMFD R13!,{R14}
TEQ R2,#6 \ is the minibuffer about to open
BEQ add_prompt
FNcall(Zap_MiniEval) \ find the number typed
LDMVSFD R13!,{PC} \ error
LDMCSFD R13!,{PC} \ wasn't a valid number
FNcall(Zap_NewMode) \ change mode
LDMFD R13!,{PC} \ finished
.add_prompt
ADR R0,prompt_string
FNcall(Zap_MiniPrompt) \ insert the prompt string
LDMFD R13!,{PC}
.prompt_string
EQUS "New mode: "+CHR$0
ALIGN
It is the offset of command_start that you must place in your command table,
not the offset of the EQUD flags word before it. Note that the command
performs the same action regardless of whether R2=0 or R2=1.
*********************
* Zap service calls *
*********************
If the second word in your command table is non zero then it gives the
module offset of a 'Zap service call handler'. This code is called at
various points to tell you about things. In general the entry/exit
conditions are:
\E R1=reason code and other registers may hold data.
R11=undefined
R12=Zaps workspace pointer as usual.
\X You should preserve R1-R13 unless otherwise stated.
R0 and flags may be corrupted.
The (current) service calls are listed below. You should ignore unrecognised
values in R1 so I can add more if necessary.
R1=0
Zap is quitting and about to kill your module. Return R0=-1 to stop it.
Your module will NOT be automatically killed if have no service call handler
(for backwards compatibility).
R1=1
Zap has just started but has not set up its heap yet.
R1=2
Zap has started and set up its heap. You should use this call to claim any
workspace via Zap_Claim.
R1=3
Zap is deleting a file. R9=file block of file being deleted. (See E-File)
R1=4
Zap is deleting a window. R8=window block of window being deleted.
(See E-Windows)